#include "weatherwindow.h"
#include "ui_weatherwindow.h"
#include "common.h"

#include <QDateTime>
#include <QTimer>
#include <QNetworkAccessManager>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

WeatherWindow::WeatherWindow(QWidget *parent) : QWidget(parent),
                                                ui(new Ui::WeatherWindow)
{
    ui->setupUi(this);

    setupSearch(ui->lineEdit_cityName);

    // 调用函数
    showTime();   // 进入天气页面时展示时间
    initVector(); // 进入天气页面时初始化容器
    getWeather(DEFAULT_ADCODE); // 进入天气页面时获取天气
}

WeatherWindow::~WeatherWindow()
{
    delete ui;
}

void WeatherWindow::setupSearch(QLineEdit *input) {
    // 连接输入框信号与槽函数
    connect(input, &QLineEdit::textChanged, this, &WeatherWindow::onTextChanged);
}

// 返回主页面按钮槽函数
void WeatherWindow::on_button_back_clicked()
{
    emit backSignal();
}

// 更新时间槽函数
void WeatherWindow::updateTime()
{
    QDateTime dateTime = QDateTime::currentDateTime();
    QString time = dateTime.toString("HH:mm:ss");

    ui->label_time->setText(time);
    if ((time.split(":")[0].toInt()) > 6 && (time.split(":")[0].toInt()) < 18)
    {
        ui->label_timeName->setText("白天");
        ui->label_timeIcon->setStyleSheet("border-image: url(:/resources/weather/day.png);");
    }
    else if ((time.split(":")[0].toInt()) > 18 && (time.split(":")[0].toInt()) < 23)
    {
        ui->label_timeName->setText("夜晚");
        ui->label_timeIcon->setStyleSheet("border-image: url(:/resources/weather/night.png);");
    }
    else
    {
        ui->label_timeName->setText("凌晨");
        ui->label_timeIcon->setStyleSheet("border-image: url(:/resources/weather/night.png);");
    }
}

// 输入框文本变化槽函数
void WeatherWindow::onTextChanged(const QString &text)
{
    if(text.isEmpty()) {
        getWeather(DEFAULT_ADCODE);
        return;
    }

    // 连接数据库
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(QString(DATABASE_PATH) + "citycode.db");
    db.open();

    // 执行数据库查询
    QSqlQuery query;
    query.prepare("SELECT id, city FROM district WHERE city LIKE '%' || :input || '%' LIMIT 1");
    query.bindValue(":input", text);

    if(!query.exec()) {
        qWarning() << "Query error:" << query.lastError().text();
        return;
    }

    // 获取查询结果
    if(query.next()) {
        qulonglong id = query.value(0).toULongLong();
        QString cityname = query.value(1).toString();
        qDebug() << "City code " << cityname << " (" << text << "): " << id;

        // 发送请求，更新天气数据
        getWeather(id);
    } else {
        getWeather(DEFAULT_ADCODE);
    }

    db.close();
}

// 更新天气槽函数
void WeatherWindow::updateWeather(QNetworkReply *reply)
{
    try
    {
        QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
        QJsonObject obj = document.object();

        // 通过json对象获取属性值
        QString getCity = obj.value("city").toString();
        ui->label_city->setText(getCity); // 城市

        QJsonArray dataArr = obj.value("data").toArray();
        for (int i = 0; i < dataArr.count(); i++)
        {
            QJsonObject dateObj = dataArr.at(i).toObject();

            QString getDay = dateObj.value("day").toString();
            this->dates->at(i)->setText(getDay.split("（")[0]);                // 日期
            this->weeks->at(i)->setText(getDay.split("（")[1].split("）")[0]); // 星期

            QString minTemperature = dateObj.value("tem2").toString();
            QString maxTemperature = dateObj.value("tem1").toString();
            QString getTemperature = minTemperature.append("℃").append("～").append(maxTemperature).append("℃");
            this->temperatures->at(i)->setText(getTemperature); // 一天温度范围

            QString getWeather = dateObj.value("wea").toString();
            this->weathers->at(i)->setText(getWeather); // 天气

            QString getIcon = dateObj.value("wea_img").toString();
            QString styleSheet = QString(R"(border-image: url(:/resources/weather/%1.png);)").arg(getIcon);
            this->icons->at(i)->setStyleSheet(styleSheet); // 天气图标

            if (i == 0) // 今天的天气
            {
                ui->label_today_icon->setStyleSheet(styleSheet); // 天气图标

                this->weeks->at(i)->setText(getDay.split("（")[1].split("）")[0].append("（今天）")); // 星期X（今天）

                QString getTodayTemperature = dateObj.value("tem").toString();
                ui->label_today_temperature->setText(getTodayTemperature.append("℃")); // 今日平均气温

                ui->label_today_weatherName->setText(getWeather);
            }
        }
    } catch (exception) {
        qWarning() << "Received data is not in proper format!";
    }
}

// 展示时间函数
void WeatherWindow::showTime()
{
    QDateTime dateTime = QDateTime::currentDateTime();
    QString time = dateTime.toString("HH:mm:ss");

    ui->label_time->setText(time);
    if ((time.split(":")[0].toInt()) > 6 && (time.split(":")[0].toInt()) < 18)
    {
        ui->label_timeName->setText("白天");
        ui->label_timeIcon->setStyleSheet("border-image: url(:/resources/weather/day.png);");
    }
    else if ((time.split(":")[0].toInt()) > 18 && (time.split(":")[0].toInt()) < 23)
    {
        ui->label_timeName->setText("夜间");
        ui->label_timeIcon->setStyleSheet("border-image: url(:/resources/weather/night.png);");
    }
    else
    {
        ui->label_timeName->setText("凌晨");
        ui->label_timeIcon->setStyleSheet("border-image: url(:/resources/weather/night.png);");
    }

    // 定时器，每隔1s获取一次时间
    QTimer *timer = new QTimer();
    connect(timer, &QTimer::timeout, this, &WeatherWindow::updateTime);
    timer->start(1000); // 1000ms
}

// 初始化容器函数
void WeatherWindow::initVector()
{
    // 初始化日期容器
    this->dates = new vector<QLabel *>();
    dates->emplace_back(ui->label_day01_date);
    dates->emplace_back(ui->label_day02_date);
    dates->emplace_back(ui->label_day03_date);
    dates->emplace_back(ui->label_day04_date);
    dates->emplace_back(ui->label_day05_date);
    dates->emplace_back(ui->label_day06_date);
    dates->emplace_back(ui->label_day07_date);

    // 初始化星期容器
    this->weeks = new vector<QLabel *>();
    weeks->emplace_back(ui->label_day01_week);
    weeks->emplace_back(ui->label_day02_week);
    weeks->emplace_back(ui->label_day03_week);
    weeks->emplace_back(ui->label_day04_week);
    weeks->emplace_back(ui->label_day05_week);
    weeks->emplace_back(ui->label_day06_week);
    weeks->emplace_back(ui->label_day07_week);

    // 初始化天气图标容器
    this->icons = new vector<QLabel *>();
    icons->emplace_back(ui->label_day01_icon);
    icons->emplace_back(ui->label_day02_icon);
    icons->emplace_back(ui->label_day03_icon);
    icons->emplace_back(ui->label_day04_icon);
    icons->emplace_back(ui->label_day05_icon);
    icons->emplace_back(ui->label_day06_icon);
    icons->emplace_back(ui->label_day07_icon);

    // 初始化天气容器
    this->weathers = new vector<QLabel *>();
    weathers->emplace_back(ui->label_day01_weatherName);
    weathers->emplace_back(ui->label_day02_weatherName);
    weathers->emplace_back(ui->label_day03_weatherName);
    weathers->emplace_back(ui->label_day04_weatherName);
    weathers->emplace_back(ui->label_day05_weatherName);
    weathers->emplace_back(ui->label_day06_weatherName);
    weathers->emplace_back(ui->label_day07_weatherName);

    // 初始化温度容器
    this->temperatures = new vector<QLabel *>();
    temperatures->emplace_back(ui->label_day01_temperature);
    temperatures->emplace_back(ui->label_day02_temperature);
    temperatures->emplace_back(ui->label_day03_temperature);
    temperatures->emplace_back(ui->label_day04_temperature);
    temperatures->emplace_back(ui->label_day05_temperature);
    temperatures->emplace_back(ui->label_day06_temperature);
    temperatures->emplace_back(ui->label_day07_temperature);
}

// 获取天气数据函数
void WeatherWindow::getWeather(qulonglong citycode)
{
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    // 向天气api发起get请求
    // http://v1.yiketianqi.com/api?unescape=1&version=v91&appid=XXX&appsecret=XXX&ext=&cityid=XXX
    QString url = QString(WEATHER_URL).arg(APPID).arg(APPSECRET).arg(citycode);
    manager->get(QNetworkRequest(QUrl(url)));

    // manager发送结束信号，updateWeather接收
    connect(manager, &QNetworkAccessManager::finished, this, &WeatherWindow::updateWeather);
}
